home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / PICSee Dust 1.01 / Preferences source / PICSPreferencesDialog.cpp < prev    next >
C/C++ Source or Header  |  1995-11-23  |  16KB  |  522 lines

  1. #include "PICSCompositeDialog.h"
  2. #include "PICS_PreferencesPanes.h"
  3.  
  4. #include "PICSViewer.h"
  5. #include "PICS_Types.h"
  6. #include "Monitors.h"    // For Place()
  7. #include "KeyUtils.h"    // To handle key-down events
  8.  
  9. #include "icl8 LDEF.h"
  10.  
  11. // ---------------------------------------------------------------------------
  12.  
  13. void InitPrefs() {
  14.     PrefsHandle prefs;
  15.     
  16.     prefs = LoadPrefs();
  17.     SetDragAndDropOperation((**prefs).defaultOperation);
  18.     ReleaseResource((Handle)prefs);
  19. } // END InitPrefs
  20.  
  21. // ---------------------------------------------------------------------------
  22.  
  23. PrefsHandle LoadPrefs() {
  24.     PrefsHandle prefs;
  25.     
  26.     prefs = (PrefsHandle)GetResource('PRFS', 128);
  27.     if (prefs == NULL) {
  28.         prefs = (PrefsHandle)NewHandleClear(sizeof(Prefs));
  29.  
  30.         (**prefs).showOpenProgress = kNeverShowOpenProgress;    // -1=always; 0=never; n=if bigger than n
  31.         (**prefs).defaultOperation = kPlayOperation;
  32.         (**prefs).compositePreview = true;
  33.         (**prefs).changeCreator = true;
  34.         (**prefs).animationMethod = kUsePictureGWorldMethod;
  35.         (**prefs).pictCreatorType = kPhotoShopCreatorType;
  36.  
  37.         (**prefs).marqueeColor = kMarqueeUseHiliteColor;
  38.         (**prefs).customRGBColor.red =
  39.         (**prefs).customRGBColor.green =
  40.         (**prefs).customRGBColor.blue = 0xFFFF;
  41.  
  42.         (**prefs).composite.doCrop = true;
  43.         (**prefs).composite.doAssemble = true;
  44.         (**prefs).composite.assembleLeftToRight = true;
  45.         (**prefs).composite.outputDepthType = kUsePICSFileOutputDepth;
  46.  
  47.         AddResource((Handle)prefs, 'PRFS', 128, "\pPrefs, dude!");
  48.         WriteResource((Handle)prefs);    
  49.     }
  50.     return(prefs);
  51. } // END LoadPrefs
  52.  
  53. // ---------------------------------------------------------------------------
  54.  
  55. void GetPrefsMarqueeColor(PrefsHandle prefs, RGBColor *marqueeColor) {
  56.     switch((**prefs).marqueeColor) {
  57.         case kMarqueeUseHiliteColor:
  58.             LMGetHiliteRGB(marqueeColor);
  59.         break;
  60.         
  61.         case kMarqueeUseBlackColor:
  62.             marqueeColor->red = marqueeColor->green = marqueeColor->blue = 0;
  63.         break;
  64.         
  65.         case kMarqueeUseCustomColor:
  66.             *marqueeColor = (**prefs).customRGBColor;
  67.         break;
  68.     }
  69. } // END GetPrefsMarqueeColor
  70.  
  71. // ---------------------------------------------------------------------------
  72.  
  73. static void DisposePrefsDialog(DialogPtr prefsDlog, Boolean savePrefs);
  74. static void PrefsDialogHandleHit(DialogPtr prefsDlog, EventRecord *theEvt, short itemHit);
  75. static Boolean PrefsDialogHandleKey(DialogPtr prefsDlog, EventRecord *theEvt);
  76. static void PrefsDialogHandleUpdate(DialogPtr prefsDlog, EventRecord *theEvt, Boolean frontMost);
  77. static void PrefsDialogHandleActivate(DialogPtr prefsDlog, Boolean activate);
  78.  
  79. static Boolean PrefsDialogGetCurrentPane(DialogPtr prefsDlog);
  80. static Boolean PrefsDialogSwitchPanes(DialogPtr prefsDlog, short paneID);
  81. static void PrefsDialogRevertPaneToDefault(DialogPtr prefsDlog);
  82.  
  83. // ---------------------------------------------------------------------------
  84.  
  85. PrefsData *sPrefsData = NULL;
  86.  
  87. static short sPanesChanged;
  88.  
  89. // ---------------------------------------------------------------------------
  90.  
  91. void SetupPrefsDialog() {
  92.     DialogPtr prefsDlog;
  93.  
  94.     if (sPrefsData == NULL) {
  95.         sPrefsData = (PrefsData*)NewPtr(sizeof(PrefsData));
  96.         sPrefsData->lastPaneUsed = kFirstPaneID;
  97.     }
  98.  
  99.     // Get a copy of the prefs
  100.     PrefsHandle prefs = LoadPrefs();
  101.     sPrefsData->prefs = prefs;
  102.     HandToHand((Handle*)&sPrefsData->prefs);
  103.     ReleaseResource((Handle)prefs);
  104.  
  105.     prefsDlog = GetNewDialog(kPrefsDlogID, NULL, (WindowPtr)-1);
  106.     SetPort(prefsDlog);
  107.  
  108.     // Setup icon list
  109.     Rect dataBounds;
  110.     Rect listRect;
  111.     Cell cSize;
  112.     IconListData theIcon;
  113.  
  114.     SetRect(&dataBounds, 0, 0, 1, kNumPanes);
  115.     GetDItemRect(prefsDlog, kPrefsDlog_PaneList, &listRect);
  116.     // Accomodate scrollbar
  117.     listRect.right -= 15;
  118.     // Set cell size based on size of list user-item
  119.     SetPt(&cSize, (listRect.right - listRect.left),
  120.         (listRect.bottom - listRect.top)/4);
  121.  
  122.     /*
  123.         If you keep forgetting (like I do ^_^), remember that
  124.         cells are like arrays: 0 is a valid cell index. A cell
  125.         of {0,0} is the topleft cell.
  126.     */
  127.     sPrefsData->paneList = LNew(&listRect, &dataBounds, cSize, kPrefsPaneListDefID,
  128.         prefsDlog, false, false, false, true);
  129.  
  130.     // Set icon parameters here.
  131.     theIcon.iconSize    = kIconBasedOnCellSize;
  132.     theIcon.frameWidth    = 2;
  133.     theIcon.drawName    = true;
  134.     theIcon.selType        = kSelectByDarkenIcon;
  135.     theIcon.id            = kOpenFilePaneID;
  136.     
  137.     // Add icons to pane list
  138.     for (short i = 0; i < kNumPanes; i++) {
  139.         SetPt(&cSize, 0, i);
  140.         LAddToCell(&theIcon, sizeof(IconListData), cSize, sPrefsData->paneList);
  141.         theIcon.id++;
  142.     }
  143.     
  144.     // Select last pane used & scroll to it if it's not visible
  145.     cSize.h = 0;
  146.     cSize.v = sPrefsData->lastPaneUsed - kFirstPaneID;
  147.     LSetSelect(true, cSize, sPrefsData->paneList);
  148.     LAutoScroll(sPrefsData->paneList);
  149.  
  150.     // Load in current pane
  151.     PrefsDialogSwitchPanes(prefsDlog, sPrefsData->lastPaneUsed);
  152.  
  153.     RegisterMovableModalDialog(prefsDlog,
  154.         PrefsDialogHandleHit,
  155.         PrefsDialogHandleKey,
  156.         PrefsDialogHandleUpdate,
  157.         PrefsDialogHandleActivate,
  158.         NULL);
  159.  
  160.     Place(prefsDlog, kCenterOnDeepDevice);
  161.     LDoDraw(true, sPrefsData->paneList);
  162.     sPanesChanged = false;    // Reset to make sure the list is updated
  163. } // END SetupPrefsDialog
  164.  
  165. // ---------------------------------------------------------------------------
  166.  
  167. void DisposePrefsDialog(DialogPtr prefsDlog, Boolean savePrefs) {
  168.     HideWindow(prefsDlog);
  169.  
  170.     if (savePrefs) {
  171.         PrefsHandle prefs = LoadPrefs();
  172.         BlockMove(*(sPrefsData->prefs), *prefs, sizeof(Prefs));
  173.         
  174.         SetPICSViewerAnimationMethod((**prefs).animationMethod);
  175.         RGBColor marqueeColor;
  176.         GetPrefsMarqueeColor(prefs, &marqueeColor);
  177.         SetPICSViewerMarqueeColor(&marqueeColor);
  178.         SetPICSViewerOpenProgress((**prefs).showOpenProgress);
  179.  
  180.         ChangedResource((Handle)prefs);
  181.         WriteResource((Handle)prefs);
  182.         ReleaseResource((Handle)prefs);
  183.     }
  184.  
  185.     LDispose(sPrefsData->paneList);
  186.     DisposeDialog(prefsDlog);
  187.     UnregisterMovableModalDialog(prefsDlog);
  188. } // END DisposePrefsDialog
  189.  
  190. // ---------------------------------------------------------------------------
  191.  
  192. void PrefsDialogHandleHit(DialogPtr prefsDlog, EventRecord *theEvt, short itemHit) {
  193.     switch(itemHit) {
  194.         case kPrefsDlog_CancelBtn:
  195.             DisposePrefsDialog(prefsDlog, false);
  196.         break;
  197.         
  198.         case kPrefsDlog_OKBtn:
  199.             // Make sure all data is valid before closing dialog;
  200.             // also forces current pane to save it's data (in case
  201.             // data is ok)
  202.             if (PrefsDialogGetCurrentPane(prefsDlog))
  203.                 DisposePrefsDialog(prefsDlog, true);
  204.         break;
  205.         
  206.         case kPrefsDlog_DefaultBtn:
  207.             PrefsDialogRevertPaneToDefault(prefsDlog);
  208.         break;
  209.         
  210.         case kPrefsDlog_PaneList:
  211.             Point listClick = theEvt->where;
  212.             GlobalToLocal(&listClick);
  213.             // Call LClick(). It returns true only for double clicks;
  214.             // but we need to check for single clicks also, which is why
  215.             // we call LGetSelect() below.
  216.             LClick(listClick, theEvt->modifiers, sPrefsData->paneList);
  217.             
  218.             Cell selectedCell = { 0, 0 };
  219.             if (LGetSelect(true, &selectedCell, sPrefsData->paneList)) {
  220.                 // Is selected pane the current pane icon or a new pane icon?
  221.                 if (sPrefsData->lastPaneUsed != (selectedCell.v + kFirstPaneID)) {                    
  222.                     if (!PrefsDialogSwitchPanes(prefsDlog, selectedCell.v + kFirstPaneID)) {
  223.                         // Unable to change panes; revert to last cell selection
  224.                         LSetSelect(false, selectedCell, sPrefsData->paneList);
  225.                         selectedCell.h = 0;
  226.                         selectedCell.v = sPrefsData->lastPaneUsed - kFirstPaneID;
  227.                         LSetSelect(true, selectedCell, sPrefsData->paneList);
  228.                     }
  229.                 }
  230.             }
  231.         break;
  232.         
  233.         case kPrefsDlog_PaneSeparatorLine:
  234.         break;
  235.         
  236.         default:
  237.             switch(sPrefsData->lastPaneUsed) {
  238.                 case kOpenFilePaneID:
  239.                     PrefsDialogOpenFilePaneHit(prefsDlog, itemHit);
  240.                 break;
  241.                 case kDragPaneID:
  242.                     PrefsDialogDragPaneHit(prefsDlog, itemHit);
  243.                 break;
  244.                 case kCompositePaneID:
  245.                     PrefsDialogCompositePaneHit(prefsDlog, itemHit);
  246.                 break;
  247.                 case kAnimPaneID:
  248.                     PrefsDialogAnimPaneHit(prefsDlog, itemHit);
  249.                 break;
  250.                 case kCreatorPaneID:
  251.                     PrefsDialogCreatorPaneHit(prefsDlog, itemHit);
  252.                 break;
  253.                 case kMarqueePaneID:
  254.                     PrefsDialogMarqueePaneHit(prefsDlog, itemHit);
  255.                 break;
  256.             }
  257.         break;
  258.     }
  259. } // END PrefsDialogHandleHit
  260.  
  261. // ---------------------------------------------------------------------------
  262.  
  263. Boolean PrefsDialogHandleKey(DialogPtr prefsDlog, EventRecord *theEvt) {
  264.     char key = theEvt->message & charCodeMask;
  265.     Boolean handledIt = false;
  266.  
  267.     switch(key) {
  268.         case kReturn_Key:
  269.             PushButton(prefsDlog, kPrefsDlog_OKBtn);
  270.             if (PrefsDialogGetCurrentPane(prefsDlog))
  271.                 DisposePrefsDialog(prefsDlog, true);
  272.             handledIt = true;
  273.         break;
  274.         
  275.         case kEscape_Key:
  276.             PushButton(prefsDlog, kPrefsDlog_CancelBtn);
  277.             DisposePrefsDialog(prefsDlog, false);
  278.             handledIt = true;
  279.         break;
  280.     }
  281.     
  282.     return(handledIt);
  283. } // END PrefsDialogHandleKey
  284.  
  285. // ---------------------------------------------------------------------------
  286.  
  287. void PrefsDialogHandleUpdate(DialogPtr prefsDlog, EventRecord *theEvt, Boolean frontMost) {
  288.     Rect lineRect;
  289.     GetDItemRect(prefsDlog, kPrefsDlog_PaneSeparatorLine, &lineRect);
  290.     GrayDrawShadowLine(&lineRect, NULL);
  291.  
  292.     /*
  293.         Slight problem here: every time we switch panes it causes an
  294.         update event. The catch is the LDEF erases & redraws the whole list
  295.         in response to an update event. But since only the pane, not the
  296.         list, changes we get a spurious update event for the list. Thus
  297.         the whole list "flickers" because it's erased & redrawn.
  298.         Solution: whenever the panes change, we set the <sPanesChanged>
  299.         static global. Here at the update routine, we check the global;
  300.         if it's false it means this is a true update event for the list.
  301.         If it's true, the panes have changed only, and we don't need
  302.         to update the list.
  303.     */
  304.     if (sPanesChanged == false) {
  305.         Rect listRect;
  306.         GetDItemRect(prefsDlog, kPrefsDlog_PaneList, &listRect);
  307.         InsetRect(&listRect, -2, -2);
  308.         GrayDrawShadowBox(&listRect, NULL);
  309.         LUpdate(prefsDlog->visRgn, sPrefsData->paneList);
  310.     }
  311.     sPanesChanged = false;
  312.     
  313.     DrawDefaultBorder(prefsDlog, kPrefsDlog_OKBtn);
  314.  
  315.     switch(sPrefsData->lastPaneUsed) {
  316.         case kOpenFilePaneID:
  317.             PrefsDialogOpenFilePaneUpdate(prefsDlog, theEvt, frontMost);
  318.         break;
  319.         case kDragPaneID:
  320.             PrefsDialogDragPaneUpdate(prefsDlog, theEvt, frontMost);
  321.         break;
  322.         case kCompositePaneID:
  323.             PrefsDialogCompositePaneUpdate(prefsDlog, theEvt, frontMost);
  324.         break;
  325.         case kAnimPaneID:
  326.             PrefsDialogAnimPaneUpdate(prefsDlog, theEvt, frontMost);
  327.         break;
  328.         case kCreatorPaneID:
  329.             PrefsDialogCreatorPaneUpdate(prefsDlog, theEvt, frontMost);
  330.         break;
  331.         case kMarqueePaneID:
  332.             PrefsDialogMarqueePaneUpdate(prefsDlog, theEvt, frontMost);
  333.         break;
  334.     }
  335. } // END PrefsDialogHandleUpdate
  336.  
  337. // ---------------------------------------------------------------------------
  338.  
  339. void PrefsDialogHandleActivate(DialogPtr prefsDlog, Boolean activate) {
  340.     short hiliteMode;
  341.  
  342.     if (activate)
  343.         hiliteMode = 0;
  344.     else
  345.         hiliteMode = 255;
  346.  
  347.     for (short i = kPrefsDlog_OKBtn; i <= kPrefsDlog_DefaultBtn; i++) {
  348.         HiliteControl((ControlHandle)GetDItemHdl(prefsDlog, i), hiliteMode);
  349.     }
  350.     DrawDefaultBorder(prefsDlog, kPrefsDlog_OKBtn);
  351.  
  352.     // Not only disable controls, but draw all text in gray too...
  353.     // Note: works only if there are no editText items in the dialog,
  354.     // else the Dialog Manager takes control over the port and
  355.     // resets the textMode (one among many variables it sets and fails
  356.     // to set back for you, rendering the port unusable for useWFont
  357.     // variations of your controls).
  358.     if (!activate) {
  359.         TextMode(grayishTextOr);
  360.         UpdateDialog(prefsDlog, prefsDlog->visRgn);
  361.     }
  362.     else {
  363.         TextMode(srcOr);
  364.         UpdateDialog(prefsDlog, prefsDlog->visRgn);
  365.     }
  366.  
  367.     // We have to call LUpdate here because LActivate affects only
  368.     // the scroll bars & the current cell selection. We need to
  369.     // gray out all cells' text via LUpdate
  370.     LUpdate(prefsDlog->visRgn, sPrefsData->paneList);
  371.     LActivate(activate, sPrefsData->paneList);
  372.  
  373.     switch(sPrefsData->lastPaneUsed) {
  374.         case kOpenFilePaneID:
  375.             PrefsDialogOpenFilePaneActivate(prefsDlog, activate);
  376.         break;
  377.         case kDragPaneID:
  378.             PrefsDialogDragPaneActivate(prefsDlog, activate);
  379.         break;
  380.         case kCompositePaneID:
  381.             PrefsDialogCompositePaneActivate(prefsDlog, activate);
  382.         break;
  383.         case kAnimPaneID:
  384.             PrefsDialogAnimPaneActivate(prefsDlog, activate);
  385.         break;
  386.         case kCreatorPaneID:
  387.             PrefsDialogCreatorPaneActivate(prefsDlog, activate);
  388.         break;
  389.         case kMarqueePaneID:
  390.             PrefsDialogMarqueePaneActivate(prefsDlog, activate);
  391.         break;
  392.     }
  393. } // END PrefsDialogHandleActivate
  394.  
  395. // ---------------------------------------------------------------------------
  396.  
  397. /*
  398.     Makes sure user can switch panes (for example, user might typed in
  399.     an invalid number in an editText field; the PrefsDialogGetxxxPaneSettings()
  400.     would return false, and we don't allow the user to switch panes).
  401. */
  402. Boolean PrefsDialogGetCurrentPane(DialogPtr prefsDlog) {
  403.     Boolean canSwitchPane;
  404.  
  405.     // Get current pane settings
  406.     switch(sPrefsData->lastPaneUsed) {
  407.         case kOpenFilePaneID:
  408.             canSwitchPane = PrefsDialogGetOpenFilePaneSettings(prefsDlog);
  409.         break;
  410.         case kDragPaneID:
  411.             canSwitchPane = PrefsDialogGetDragPaneSettings(prefsDlog);
  412.         break;
  413.         case kCompositePaneID:
  414.             canSwitchPane = PrefsDialogGetCompositePaneSettings(prefsDlog);
  415.         break;
  416.         case kAnimPaneID:
  417.             canSwitchPane = PrefsDialogGetAnimPaneSettings(prefsDlog);
  418.         break;
  419.         case kCreatorPaneID:
  420.             canSwitchPane = PrefsDialogGetCreatorPaneSettings(prefsDlog);
  421.         break;
  422.         case kMarqueePaneID:
  423.             canSwitchPane = PrefsDialogGetMarqueePaneSettings(prefsDlog);
  424.         break;
  425.     }
  426.  
  427.     return(canSwitchPane);
  428. } // END PrefsDialogGetCurrentPane
  429.  
  430. // ---------------------------------------------------------------------------
  431.  
  432. Boolean PrefsDialogSwitchPanes(DialogPtr prefsDlog, short paneID) {
  433.     short removeCount;
  434.  
  435.     if (sPrefsData->lastPaneUsed != paneID) {
  436.         // Get current pane settings only if panes have changed
  437.         // (they might not have changed; we could have been called
  438.         // from SetupPrefDialog().
  439.         if (!PrefsDialogGetCurrentPane(prefsDlog))
  440.             return(false);
  441.     }
  442.  
  443.     // Remove current pane DITL
  444.     removeCount = CountDITL(prefsDlog) - kPrefsDlog_LastItem + 1;
  445.     if (removeCount > 0) {
  446.         ShortenDITL(prefsDlog, removeCount);
  447.     }
  448.  
  449.     // Add new pane's DITL
  450.     Handle ditl;
  451.     ditl = GetResource('DITL', paneID);
  452.     if (ditl != NULL) {
  453.         AppendDITL(prefsDlog, ditl, overlayDITL);
  454.         ReleaseResource(ditl);
  455.     }
  456.     sPrefsData->lastPaneUsed = paneID;
  457.  
  458.     // Tell pane to initialize it's items
  459.     switch(paneID) {
  460.         case kOpenFilePaneID:
  461.             PrefsDialogSetupOpenFilePane(prefsDlog);
  462.         break;
  463.         case kDragPaneID:
  464.             PrefsDialogSetupDragPane(prefsDlog);
  465.         break;
  466.         case kCompositePaneID:
  467.             PrefsDialogSetupCompositePane(prefsDlog);
  468.         break;
  469.         case kAnimPaneID:
  470.             PrefsDialogSetupAnimPane(prefsDlog);
  471.         break;
  472.         case kCreatorPaneID:
  473.             PrefsDialogSetupCreatorPane(prefsDlog);
  474.         break;
  475.         case kMarqueePaneID:
  476.             PrefsDialogSetupMarqueePane(prefsDlog);
  477.         break;
  478.     }
  479.     
  480.     sPanesChanged = true;
  481.     return(true);
  482. } // END PrefsDialogSwitchPanes
  483.  
  484. // ---------------------------------------------------------------------------
  485.  
  486. void PrefsDialogRevertPaneToDefault(DialogPtr prefsDlog) {
  487.     switch(sPrefsData->lastPaneUsed) {
  488.         case kOpenFilePaneID:
  489.             (**sPrefsData->prefs).showOpenProgress = kNeverShowOpenProgress;
  490.             PrefsDialogSetupOpenFilePane(prefsDlog);
  491.         break;
  492.  
  493.         case kDragPaneID:
  494.             (**sPrefsData->prefs).defaultOperation = kPlayOperation;
  495.             PrefsDialogSetupDragPane(prefsDlog);
  496.         break;
  497.  
  498.         case kCompositePaneID:
  499.             (**sPrefsData->prefs).compositePreview = true;
  500.             PrefsDialogSetupCompositePane(prefsDlog);
  501.         break;
  502.  
  503.         case kAnimPaneID:
  504.             (**sPrefsData->prefs).animationMethod = kUsePictureGWorldMethod;
  505.             PrefsDialogSetupAnimPane(prefsDlog);
  506.         break;
  507.         
  508.         case kCreatorPaneID:
  509.             (**sPrefsData->prefs).pictCreatorType = kPhotoShopCreatorType;
  510.             PrefsDialogSetupCreatorPane(prefsDlog);
  511.         break;
  512.  
  513.         case kMarqueePaneID:
  514.             (**sPrefsData->prefs).marqueeColor = kMarqueeUseHiliteColor;
  515.             (**sPrefsData->prefs).customRGBColor.red =
  516.             (**sPrefsData->prefs).customRGBColor.green =
  517.             (**sPrefsData->prefs).customRGBColor.blue = 0xFFFF;
  518.             PrefsDialogSetupMarqueePane(prefsDlog);
  519.         break;
  520.     }
  521.     sPanesChanged = true;
  522. } // END PrefsDialogReverPaneToDefault